#!/usr/bin/python
'''
Created on 23 May 2010

@author: greg
'''
import sys, re, getopt, commands
from compiler.ast import For
import os
class AndroidXmlTestReporter():
   
   testpattern = re.compile('^INSTRUMENTATION_STATUS: class=.*?INSTRUMENTATION_STATUS_CODE: .*?$',re.DOTALL|re.MULTILINE)
   testcasepattern = re.compile('^.*?test=(.*?)$',  re.MULTILINE)
   testsuiteclasspattern = re.compile('^.*?class=(.*?)$', re.MULTILINE)
   
   def readreport(self):
      return sys.stdin.readlines()
   def createheader(self):
      return '<?xml version="1.0" encoding="UTF-8"?>\n'

   def getsuiteclass(self, testsuite):
      return self.testsuiteclasspattern.search(testsuite).group(1)
   
   def gettests(self, testsuite, previous):
      xmlfrag =''
      testcases = set(self.testcasepattern.findall(testsuite))
      for testcase in testcases:
         if not testcase in previous:
            self.numtests += 1
            xmlfrag+='<testcase name="%(testcase)s" classname="%(suiteclassname)s" time="1.284"/>' % {'testcase':testcase[:-1],'suiteclassname':self.suiteclassname}
            previous.append(testcase)
      return xmlfrag
      
   def getsuitesforclassname(self,  testsuites):
      xmlfrag = '<testsuite name="%(classname)s" time="0.00">' %{'classname':self.suiteclassname}
      previouscases = []
      for testsuite in testsuites:
         testsuiteclassname = self.getsuiteclass(testsuite)[:-1]
         if (testsuiteclassname == self.suiteclassname):
            xmlfrag += self.gettests(testsuite, previouscases)
      xmlfrag +='</testsuite>'
      return xmlfrag
      
   def getsuites(self, inputdata):
      xml=''
      testsuites = self.testpattern.findall(inputdata)
      classnames = set(map(self.getsuiteclass, testsuites))
      for classname in classnames:
         self.suiteclassname = classname[:-1]
         xml+=self.getsuitesforclassname(testsuites)
      return xml 
   
   def transformreport(self, inputdata):
      self.numtests = 0
      xml = ''
      xml += self.createheader()
      suites= self.getsuites(inputdata)
      self.package=re.match("(\S*)\.\S*", self.suiteclassname).group(1)
      xml +='<testsuites name="%(package)s" project="%(projectname)s" tests="%(numtests)d" started="%(numtests)d" failures="0" errors="0" ignored="0">%(suites)s</testsuites>' % {'projectname':os.path.basename(os.getcwd()),'package':self.package,'numtests':self.numtests,'suites':suites}
      return xml

   def getreport(self, package):
      
      cmd = 'adb shell am instrument -w -r %s/android.test.InstrumentationTestRunner' % package
      return commands.getstatusoutput(cmd)
   
   def writereport(self, xmlreport):
      f = open('./target/test-report-%s-android.xml'%self.package, 'w')
      f.write(xmlreport)
      f.close()
      
   
   def usage(self):
      print ' xml reporter 2010 extreme beta '
      print 'requires:  a folder inside project root called target'
      print '           run from project root'
      print '           device or emulator connected'
      print '           instrumentation project deployed to device'
      print '-h             print help'
      print '-p|--package   fully qualified package containing android instrumentation tests'
      

   def main(self, argv):         
      try:                                
         opts, args = getopt.getopt(argv, "hp:", ["help", "package="]) 
         if (opts == None or len(opts) == 0):
            self.usage()                          
            sys.exit(2)
         for opt, arg in opts:                
            if opt in ("-h", "--help"):      
               self.usage()                     
               sys.exit()                  
            elif opt in ("-p", "--package"): 
               status, output = self.getreport(arg)       
               if (status <> 0):
                  print 'Error running test\n' , output
                  sys.exit(2)
               print 'output is ', output
               xmlreport = self.transformreport(output)
               self.writereport(xmlreport)   
      except getopt.GetoptError:           
         self.usage()                          
         sys.exit(2)                  
            

if __name__ == "__main__":      
   a = AndroidXmlTestReporter()
   a.main(sys.argv[1:])

